package com.amap.search.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class RestHttpUtil {
    @Resource
    private RestTemplate restTemplate;

    @Resource
    private Environment env;

    public static ConcurrentHashMap<String, Integer> requestCountMap = new ConcurrentHashMap<>();

    public static int getRequestCount = 0;

    public int batch = 70;

    /**
     * 处理get请求
     */
    public <R> R getRequest(String url, Map<String, String> paramMap, Class<R> clazz){
        // 统计每个url请求次数
        requestCountMap.put(url, requestCountMap.getOrDefault(url, 0) + 1);
        getRequestCount++;
        if(requestCountMap.get(url) >= batch){
            throw new RuntimeException("请求次数超过设定上限");
        }

        if(MapUtils.isNotEmpty(paramMap)){
            StringBuilder sb = new StringBuilder(url);
            sb.append("?");
            boolean first = true;
            for(Map.Entry<String, String> entry : paramMap.entrySet()){
                if(!first){
                    sb.append("&");
                }
                first = false;
                sb.append(entry.getKey()).append("=").append(entry.getValue());
            }
            url = sb.toString();
        }
        log.info("request url is : " + url);
        ResponseEntity<R> response = restTemplate.getForEntity(url, clazz);
        if(response.getStatusCode().is2xxSuccessful()){
            return response.getBody();
        }
        throw new RuntimeException("xxx");
    }

    public <T, R> R getRequest(String url, T param, Class<R> clazz){
        try {
            Map<String, String> paramMap = objectToStrMap(param);
            return getRequest(url, paramMap, clazz);
        }
        catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    // 自定义对象
    public <T, R> R postRequest(String url, T body, Class<R> clazz) {
        HttpEntity httpEntity = new HttpEntity(body, new HttpHeaders());
        ResponseEntity<R> response = restTemplate.postForEntity(url, httpEntity, clazz);
        if (response.getStatusCode().is2xxSuccessful()) {
            return response.getBody();
        }
        throw new RuntimeException("xxx");
    }


    // String对象
    public <T> String postRequest(String url, T body) {
        HttpEntity httpEntity = new HttpEntity(body, new HttpHeaders());
        ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, String.class);
        if (response.getStatusCode().is2xxSuccessful()) {
            return response.getBody();
        }
        throw new RuntimeException("xxx");
    }

    public <R> R getRequest(String url, Class<R> clazz){
        ResponseEntity<R> response = restTemplate.getForEntity(url, clazz);
        if(response.getStatusCode().is2xxSuccessful()){
            return response.getBody();
        }
        throw new RuntimeException("xxx");
    }


    public HttpHeaders getAuthHeader(String username, String password) {
        HttpHeaders httpHeaders = new HttpHeaders();
        String separator = ":";
        String encodeStr = "Basic " + Base64.getEncoder().encodeToString((username + separator + password).getBytes());
        httpHeaders.set(HttpHeaders.AUTHORIZATION, encodeStr);
        return httpHeaders;
    }

    private <T> Map<String, String> objectToStrMap(T t) throws IllegalAccessException {
        Map<String, String> objStrMap = new HashMap<>();
        Field[] objFields = t.getClass().getDeclaredFields();
        Field.setAccessible(objFields, true);
        if(objFields != null && objFields.length > 0){
            for(int i=0; i<objFields.length; i++) {
                Object value = objFields[i].get(t);
                if (value != null && StringUtils.isNotBlank(String.valueOf(value))) {
                    objStrMap.put(String.valueOf(objFields[i].getName()), String.valueOf(value));
                }
            }
        }
        return objStrMap;
    }

//    public <T, R> R postRequest (String url, T body){
//        HttpEntity httpEntity = new HttpEntity(body, new HttpHeaders());
//        ResponseEntity response = restTemplate.postForEntity(url, httpEntity, Object.class);
//        if(response.getStatusCode().is2xxSuccessful()){
//            return (R) response.getBody();
//        }
//        throw new RuntimeException("xxx");
//    }
}
